package cn.magicman.pool;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

//线索是从tomcat中，发现的线程池，接着探索 池化
// 最后到这里的  最简对象池
public class ObjectPoolDemo {

    // 1. 定义要池化的资源（例如数据库连接）
    static class PooledObject {
        private int id;
        private boolean inUse;
        
        public PooledObject(int id) {
            this.id = id;
            this.inUse = false;
            System.out.println("✅ 创建新对象: " + this);
        }
        
        public void use() {
            inUse = true;
            System.out.println("🔥 使用对象: " + this);
        }
        
        public void reset() {
            inUse = false;
            System.out.println("🔄 重置对象: " + this);
        }
        
        @Override
        public String toString() {
            return "Object#" + id + (inUse ? " [使用中]" : " [空闲]");
        }
    }

    // 2. 实现简单的对象池
    static class SimpleObjectPool {
        private final Queue<PooledObject> available = new LinkedList<>();
        private final int maxSize;
        private int counter = 0;
        private final Lock lock = new ReentrantLock();
        
        public SimpleObjectPool(int maxSize) {
            this.maxSize = maxSize;
        }
        
        public PooledObject borrow() {
            lock.lock();
            try {
                // 1. 池中有空闲对象则直接使用
                PooledObject obj = available.poll();
                if (obj != null) {
                    obj.use();
                    return obj;
                }
                
                // 2. 池中无对象且未达上限，创建新对象
                if (counter < maxSize) {
                    obj = new PooledObject(++counter);
                    obj.use();
                    return obj;
                }
                
                // 3. 池已满且无空闲对象（实际应阻塞等待，这里简化处理）
                throw new RuntimeException("池已满，无法获取新对象");
            } finally {
                lock.unlock();
            }
        }
        
        public void release(PooledObject obj) {
            lock.lock();
            try {
                obj.reset();
                available.offer(obj);
                System.out.println("📦 对象已归还，池中空闲: " + available.size());
            } finally {
                lock.unlock();
            }
        }
    }

    // 3. 测试主方法
    public static void main(String[] args) {
        // 创建容量为2的对象池
        SimpleObjectPool pool = new SimpleObjectPool(2);
        
        System.out.println("\n===== 第一次获取 =====");
        PooledObject obj1 = pool.borrow();
        
        System.out.println("\n===== 第二次获取 =====");
        PooledObject obj2 = pool.borrow();

//        System.out.println("\n===== 第三次获取 =====");
//        PooledObject obj3 = pool.borrow();
        
        System.out.println("\n===== 归还第一个对象 =====");
        pool.release(obj1);
        System.out.println("\n===== 归还第二个对象 =====");
        pool.release(obj2);
//        System.out.println("\n===== 归还第三个对象 =====");
//        pool.release(obj3);

        System.out.println("\n===== 第四次获取 =====");
        PooledObject obj4 = pool.borrow();  // 应该复用obj1
        
        System.out.println("\n===== 检查是否同一对象 =====");
        System.out.println("obj1 == obj4? " + (obj1 == obj4));
    }
}